package com.test.security.springsecuritydemo12.filter;

import com.test.security.springsecuritydemo12.auth.OtpAuthentication;
import com.test.security.springsecuritydemo12.auth.UsernamePasswordAuthentication;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Objects;
import javax.crypto.SecretKey;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.web.filter.OncePerRequestFilter;

/**
 * Created with IntelliJ IDEA.
 * Description:
 *
 * @author lzy
 * @since 2023/1/5 上午11:37
 */
public class InitialAuthenticationFilter extends OncePerRequestFilter {
    private AuthenticationManager manager;

    public void setManager(AuthenticationManager manager) {
        this.manager = manager;
    }

    @Value("${jwt.signing.key}")
    private String signingkey;

    /**
     * @param request
     * @param response
     * @param filterChain
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        final String username = request.getHeader("username");
        final String password = request.getHeader("password");
        final String code = request.getHeader("code");

        if (Objects.isNull(code)) {
            Authentication auth = new UsernamePasswordAuthentication(username, password);
            manager.authenticate(auth);
        } else {
            Authentication auth = new OtpAuthentication(username, code);
            auth = manager.authenticate(auth);
            final SecretKey key = Keys.hmacShaKeyFor(signingkey.getBytes(StandardCharsets.UTF_8));
            final String jwt = Jwts.builder()
                    .setClaims(Map.of("username", username))
                    .signWith(key)
                    .compact();
            response.setHeader("Authorization", jwt);
        }

        filterChain.doFilter(request, response);
    }

    /**
     * @param request current HTTP request
     * @return
     * @throws ServletException
     */
    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
        return !request.getServletPath().equals("/login");
    }
}
